package com.projecthost.util;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.Cacheable;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;

public class HtmlParser {

    private final static Logger logger = LoggerFactory.getLogger(HtmlParser.class);

    private final WebClient webClient = new WebClient();

    @Cacheable("WEB_PAGES_BY_URL")
    public HtmlPage getHtmlPageFromUrl(String url, boolean javaScriptOn) {
        try {
            webClient.setJavaScriptEnabled(javaScriptOn);
            HtmlPage page = webClient.getPage(url);
            if (logger.isTraceEnabled()) {
                logger.trace("Contents of {}\n{}", url, page.getWebResponse().getContentAsString());
            }
            return page;
        } catch (Exception ex) {
            throw new PageCreationException("Couldn't get contents for page " + url, ex);
        }
    }

    public <T> List<T> evalutateMultiple(HtmlPage element, String xpath) {
        try {
            @SuppressWarnings("unchecked")
            List<T> elements = (List<T>) element.getByXPath(xpath);
            return elements;
        } catch (Exception ex) {
            throw new XpathEvaluationException("Could not evaluate xpath query " + xpath + " in provided element", ex);
        }
    }

    public <T> T evalutateSingle(HtmlPage element, String xpath) {
        List<T> evalutateMultiple = evalutateMultiple(element, xpath);
        if (evalutateMultiple.size() > 1) {
            throw new InvalidParsingResult("Expected 1 element back but was: " + evalutateMultiple.size());
        }
        if (evalutateMultiple.size() == 0) {
            return null;
        }
        return evalutateMultiple.get(0);
    }

}
